/*********************************************************************************************************
**
**                                   GJB 标准测试集
**
**                               Copyright All Rights Reserved
**
**--------------文件信息--------------------------------------------------------------------------------
**
** 文   件   名: gjb_S0101204GN_3.c
**
** 文件创建日期: 2021 年 1 月 12 日
**
** 描        述: 看门狗定时器启动， 单次, 使用无效看门狗ID；
*********************************************************************************************************/

#ifdef SYLIXOS
#define __SYLIXOS_KERNEL
#endif

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>
#include "signal.h"
#include <string.h>

#define MAX_WDG_NUM 64
#define SYSTEM_TICKS_USEC        1000
#define ECALLEDINISR                11
#define SYSTEM_TICKS_NANO        100000
#define EMNOTINITED 0x7A

typedef void (*wdg_func)(void *);
typedef int 			wdg_t;
typedef struct __wdg_attr
{
    unsigned int used;
    timer_t timerid;
    int ticks;
    int is_start;
    int is_execed;
    struct sigevent evp;
    void *args;
    wdg_func func;
}wdg_attr;
wdg_attr g_wdg[MAX_WDG_NUM];

static int nCount_tma_2043 = 0;

int wdg_create(wdg_t *wdg_id)
{
    int id = 0;
    if(wdg_id == NULL)
        return -1;
    for(id = 1; id < MAX_WDG_NUM; id++)
    {
        if(g_wdg[id].used == 0)
            break;
    }
    if(id == MAX_WDG_NUM)
    {
        errno = EAGAIN;
        return -1;
    }
    g_wdg[id].used = 1;
    g_wdg[id].is_start = 0;
    //    wdg_t id=wdCreate();
    *wdg_id = id;
    //    printf("wdg_create %d\n", *wdg_id);
    return 0;
}

// TODO:该函数与glibc-2.28/sysdeps/mach/hurd/setitimer.c的函数有冲突
static void timer_thread(union sigval v)
{
    //    printf("timer_thread function! %d %d 0x%lx 0x%lx\n",
    //           v.sival_int,
    //           g_wdg[v.sival_int].is_execed,
    //            &g_wdg[v.sival_int].is_execed,
    //            g_wdg[v.sival_int].func);
    if(g_wdg[v.sival_int].func != NULL && (g_wdg[v.sival_int].is_execed == 0))
    {
        g_wdg[v.sival_int].is_execed = 1;
        g_wdg[v.sival_int].func(g_wdg[v.sival_int].args);
        //        printf("timer_thread set g_wdg[%d].is_execed %d 0x%lx\n",
        //               v.sival_int,
        //               g_wdg[v.sival_int].is_execed,
        //                &gGJB_PRT_INFO_wdg[v.sival_int].is_execed);
    }
}
int wdg_start(wdg_t wdg_id,int ticks,void (*func)(void *arg),void *arg)
{
    int val;
    struct itimerspec it;
    if(wdg_id < 1 || wdg_id >= MAX_WDG_NUM)
    {
        errno = EAGAIN;
        return -1;
    }
    if ((func == NULL) && (arg == NULL))
    {
        return 0;
    }
    if(func == NULL)
    {
        return -1;
    }
    //    printf("wdg_start wdg_id  %d\n", wdg_id);
    memset(&g_wdg[wdg_id].evp, 0, sizeof(struct sigevent));
    g_wdg[wdg_id].evp.sigev_value.sival_int = wdg_id;                //也是标识定时器的，回调函数可以获得
    g_wdg[wdg_id].evp.sigev_notify = SIGEV_THREAD;                //线程通知的方式，派驻新线程
    g_wdg[wdg_id].evp.sigev_notify_function = timer_thread;               //线程函数地址
    g_wdg[wdg_id].func = func;
    g_wdg[wdg_id].args = arg;

    if(g_wdg[wdg_id].is_start == 0)
    {
        //    printf("timer_create %d\n", ticks);
        val = timer_create(CLOCK_REALTIME, &g_wdg[wdg_id].evp, &g_wdg[wdg_id].timerid);
        if(val < 0)
        {
            printf("timer_create err %d %d\n", val, errno);
            return val;
        }
        g_wdg[wdg_id].is_start = 1;
    }
    g_wdg[wdg_id].is_execed = 0;
    //    printf("set g_wdg[%d].is_execed %d 0x%lx\n",
    //           wdg_id,
    //           g_wdg[wdg_id].is_execed,
    //           &g_wdg[wdg_id].is_execed);
    g_wdg[wdg_id].ticks = ticks;
    it.it_interval.tv_sec = 0;
    it.it_interval.tv_nsec = g_wdg[wdg_id].ticks * SYSTEM_TICKS_NANO;
    it.it_value.tv_sec = 0;
    it.it_value.tv_nsec = 1000;//g_wdg[wdg_id].ticks * SYSTEM_TICKS_NANO;//1000

    //    printf("timer_settime\n");
    //    usleep(10);
    val = timer_settime(g_wdg[wdg_id].timerid, 0, &it, NULL);
    if(val < 0)
    {
        ;
        //        printf("timer_settime err %d %d\n", val, errno);
    }
    //    printf("timer_settime %d\n", val);
    //    val=wdStart(wdg_id,ticks,func,arg);
    return val;
}


void Fun1_tma_2043 (void* arg)
{
    nCount_tma_2043++;
}

//看门狗测试入口函数
int Test_Wdg_gn_tma_2043 (void)
{
    wdg_t wdg_id;
    int res;

    //创建看门狗
    res = wdg_create(&wdg_id);
    if (res == 0) {
        printf("300--Pass--wdg_create(&wdg_id)\n");
    } else {
        printf("301--Fail--wdg_create(&wdg_id)\n");
        return -1;
    }

    //启动看门狗
    res = wdg_start(0, 100, Fun1_tma_2043, NULL);
    sleep(1);

    if ((res == -1) && (nCount_tma_2043 == 0)) {
        printf("302--Pass--wdg_start(wdg_id,100,Fun1,&cstr)\n");
        return 0;

    } else {
        printf("303--Fail--wdg_start(wdg_id,100,Fun1,&cstr)\n");
        return -1;
    }

    return 0;
}
/***************************GJB_PRT_INFO*******************************************
 * 函数名称： void usrMain(void)
 * 功能描述： 用户程序入口
 * 输入参数： 无
 * 输出参数： 无
 * 返 回 值： 无
 * 其它说明： 无
 **************************************************************************/
int main()
{
    int  result;

    result = Test_Wdg_gn_tma_2043();
    if (result != 0) {
        printf("<RSLT>..................................................[GJB_FAILED]\n");
        return -1;
    }

    printf("<RSLT>..................................................[GJB_PASS]\n");
    return 0;
}
